今天分享一個特別的東西 Git Hooks,會研究這個是因為我想將不同專案的 commit 紀錄起來,方便之後查閱,查了一些資料發現原來 Git 本身有提供 Hooks(鉤子) 的功能,可以在 commit 的前後執行我們寫的 Script,一般常用來檢查提交訊息是否符合團隊規定,或執行自動化測試等等,而我的用法好像比較特別。
![]()
Git Hooks 可以用的 Script 有很多,這篇我就用自己相對熟悉的 Python 語言,前陣子有用來練習一些題目,可以較快上手。
每個 Git 專案下都有個 .git 的隱藏資料夾,git hooks 就放在 .git 裡面的 hooks 資料夾內,開啟後可以看到 .sample 副檔名的檔案。

Hooks 的種類很多,我用到的是 commit-msg,它會在用戶提交訊息後被執行,利用這個 hook 就可以在提交後,執行紀錄 commit 的腳本。
#!/usr/bin/python
import sys
import os
import re
import csv
import datetime
import subprocess
commit_msg_filepath = sys.argv[1]
with open(commit_msg_filepath, 'r', encoding='UTF-8') as f:
dateTime = datetime.datetime.now().strftime("%Y-%m-%d")
name = subprocess.check_output(['git', 'show', '-s', '--format=%an']).decode('UTF-8').strip()
content = f.read().strip('\n')
branch = subprocess.check_output(['git', 'symbolic-ref', '-q', '--short', 'HEAD']).decode('UTF-8').strip()
project = os.path.basename(os.getcwd())
# 改成自己的存放路徑
csvPath = 'C:\\CommitLog\\CommitLog.csv'
with open(csvPath, 'a', encoding='Big5', newline='') as csvFile:
writer = csv.writer(csvFile, quotechar='"', quoting = csv.QUOTE_ALL)
writer.writerow([dateTime, project, name, content, branch])
print('Commit log created!!!')
sys.exit(0)
1. dateTime (提交日期)
現在時間只取日期的部分
2. name (用戶名稱)
這裡用到 git 指令 git show -s --format=%an 可以取得用戶名
3. content (提交訊息)
從 sys.argv[1] 可以取得儲存提交訊息的檔案路徑
4. branch (分支)
同樣用到 git 指令 git symbolic-ref -q --short HEAD 取得當前分支
5. project (專案名稱)
從腳本存放的路徑取得
程式中 print 的內容可以在 commit 視窗看到

程式最後的 sys.exit(0) 代表該 hooks 執行成功,將 0 改為 1 則代表失敗,就會出現上圖不正常結束的訊息。
還有一點要特別注意,想要啟動 hooks 需要將 .sample 副檔名拿掉,這邊讓我卡關好久,不管怎麼改程式都沒反應,原來沒有 .sample 才是 hooks 的正確檔名。
![]()
原來想將結果製作成 Excel,但沒有 Python 存取 Excel 的經驗,所以偷懶改用 CSV,Excel 開啟後感覺差不多,不過還是歡迎有經驗的大大,推薦好用的 Excel 套件給小弟,今天就到這裡摟,感謝大家觀看。